package com.hardware.service.impl;

import com.hardware.dll.AidierDLL;
import com.hardware.entity.AidierInit;
import com.hardware.entity.CardInfo;
import com.hardware.entity.Respond;
import com.hardware.enums.AidierStatus;
import com.hardware.service.AidierService;
import com.hardware.utils.MyDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;

/**
 * 爱迪尔门锁系统
 *
 * @作者 韩宗森
 * @创建时间 2024年10月24日 15:50
 */
@Service
@Slf4j
public class AidierServiceImpl implements AidierService {

    // 初始化 门锁参数
    public String initDoor(Integer softwareIn, String serverIn, String usernameIn, Integer portIn, Integer encoderIn, Integer TmEncoderIn) {
        System.out.println(MyDateUtil.currentTime() + "softwareIn: " + softwareIn + "; serverIn: " + serverIn + "; usernameIn: "
                + usernameIn + "; portIn: " + portIn + "; encoderIn: " + encoderIn+ "; TmEncoderIn: " + TmEncoderIn);
        log.info("initDoor....");

        String msg = "";
        try {
            int software = softwareIn;
            byte[] server = serverIn.getBytes("GBK");
            byte[] username = usernameIn.getBytes("GBK");
            int port = portIn;
            int Encoder = encoderIn;
            int TMEncoder = TmEncoderIn;
            // 开始 初始化
            int ret = AidierDLL.INSTANCE.Init(software, server, username, port, Encoder, TMEncoder);

            AidierStatus aidierStatus = AidierStatus.fromKey(ret);

            msg = "状态码: " + aidierStatus.getKey() + ", 说明: " + aidierStatus.getValue();
            log.info("接口初始化: " + msg);
            return msg;
        } catch (UnsupportedEncodingException e) {
            System.out.println("String转byte 有异常...");
            e.printStackTrace();
        }
        return msg;
    }

    // 接口初始化
    @Override
    public Respond initDoorInterface(AidierInit aidierInit) {
        String msg = initDoor(aidierInit.getSoftwareIn(), aidierInit.getServerIn(), aidierInit.getUsernameIn(), aidierInit.getPortIn(),
                aidierInit.getEncoderIn(), aidierInit.getTmEncoderIn());

        Respond respond = new Respond();
        respond.setStatus(1);
        respond.setMsg(msg);
        return respond;
    }

    // 关闭资源接口
    @Override
    public Respond close() {
        int ret = AidierDLL.INSTANCE.EndSession();
        AidierStatus aidierStatus = AidierStatus.fromKey(ret);
        String msg = "状态码: " + aidierStatus.getKey() + ", 说明: " + aidierStatus.getValue();
        log.info("关闭资源: " + msg);
        Respond respond = new Respond();
        respond.setStatus(1);
        respond.setMsg(msg);

        return respond;
    }

    // 爱迪尔门锁系统
    @Override
    public void aidierDoor() {
        Respond respond = new Respond();

        /*
         * 1. 初始化函数
         *
         * @param software  指定门锁系统
         * @param server    指定门锁系统数据库安装的服务器（SQL Server）名。
         * @param username  用户名，用于门锁系统记录操作人员。
         * @param port      串口号，1-COM1，2-COM2，3-COM3，4-COM4依次类推。
         * @param Encoder   发行机类型，0-手动发行机，1-自动发行机，2-MSR206（磁卡）。
         * @param TMEncoder TM发行机类型，1-DS9097E，5-DS9097U
         * @return
         */
        int software = 1;
        byte[] server = new byte[31];
        byte[] username = new byte[31];
        int port = 1;
        int Encoder = 0;
        int TMEncoder = 1;

        // 开始 初始化
        int ret = AidierDLL.INSTANCE.Init(software, server, username, port, Encoder, TMEncoder);

        try {
            System.out.println("server: " + new String(server, "GBK").trim());
            System.out.println("username: " + new String(server, "GBK").trim());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        if (ret != 1) {
            AidierStatus aidierStatus = AidierStatus.fromKey(ret);
            respond.setMsg("没有找到读卡器!");
            System.out.println("没有找到读卡器! 状态码: " + aidierStatus.getKey() + ", 说明: " + aidierStatus.getValue());
        } else {
            System.out.println("读卡器连接成功!");

            // TODO  继续操作
            // 发行新客人卡
        }
        // 关闭 结束工作期
        ret = AidierDLL.INSTANCE.EndSession();
        if (ret == 0) {
            System.out.println("结束工作期成功!");
            System.out.println("---------------------------------------------------------------------");

        } else {
            System.out.println("结束工作期错误! 错误码: " + ret);
        }


    }

    // 发卡
    @Override
    public Respond newCard(CardInfo cardInfo) {
        Respond respond = new Respond();
        respond.setStatus(1);
        try {
            String stimeText = cardInfo.getStarTime() + cardInfo.getEndTime();
            // 先转字符
            byte[] room = cardInfo.getRoom().getBytes("GBK"); // 6字节字符串，必须是门锁系统设置的房号
            byte[] gate = "00".getBytes("GBK"); // 公共通道，字符串参数，“00”表示按默认授权通道，“99”表示授权所有公共通道，其他为指定通道代码。例如：“010203”表示授权01、02、03三个通道。
            byte[] stime = stimeText.getBytes("GBK");

            int ret = AidierDLL.INSTANCE.NewKey(room, gate, stime, null, null, 1, 0, null, null);
            AidierStatus aidierStatus = AidierStatus.fromKey(ret);
            String msg = "状态码: " + aidierStatus.getKey() + ", 说明: " + aidierStatus.getValue();

            // 复制卡
            if (1 == cardInfo.getIsCopy()) {
                int retCopy = AidierDLL.INSTANCE.DupKey(room, gate, stime, null, null, 1, 0, null, null);
                AidierStatus copyStatus = AidierStatus.fromKey(retCopy);
                System.out.println(MyDateUtil.currentTime() + "复制卡 DupKey():状态码: " + copyStatus.getKey() + ", 说明: " + copyStatus.getValue());
                msg += "\n复制卡 DupKey():状态码: " + copyStatus.getKey() + ", 说明: " + copyStatus.getValue();

            }
            log.info("发卡: " + msg);
            respond.setMsg(msg);
            return respond;
        } catch (UnsupportedEncodingException e) {
            System.out.println("String转byte 有异常...");
            e.printStackTrace();
        }
        respond.setStatus(0);
        respond.setMsg("未知异常...");
        return respond;
    }

    // 读卡
    @Override
    public Respond readCard() {
        Respond respond = new Respond();
        respond.setStatus(1);

        byte[] room = new byte[31]; // 接收返回的房号，建议10字节。
        byte[] gate = new byte[31]; // 接收返回的授权公共通道
        byte[] stime = new byte[31]; // 起止时间，24字节字符串
        byte[] guestname = new byte[31]; // 接收返回的客人姓名
        byte[] guestid = new byte[31]; // 接收返回的客人ID
        long cardno = 0; // 接收返回的卡号
        int st = 0; // 整形指针，接收返回的卡状态，1-正常使用，3-正常注销，4-遗失注销，5-损毁注销，6-自动注销。可以为NULL。
        int ret = AidierDLL.INSTANCE.ReadCard(room, gate, stime, guestname, guestid, null, null, cardno, st);
        AidierStatus aidierStatus = AidierStatus.fromKey(ret);
        String msg = "状态码: " + aidierStatus.getKey() + ", 说明: " + aidierStatus.getValue();
        log.info("读卡: " + msg);

        try {
            String roomOut = new String(room, "GBK").trim();
            String gateOut = new String(gate, "GBK").trim();
            String stimeOut = new String(stime, "GBK").trim();
            String guestnameOut = new String(guestname, "GBK").trim();
            String guestidOut = new String(guestid, "GBK").trim();

            System.out.println(MyDateUtil.currentTime()
                    + "roomOut: " + roomOut
                    + ", gateOut: " + gateOut
                    + ", stimeOut: " + stimeOut
                    + ", guestnameOut: " + guestnameOut
                    + ", guestidOut: " + guestidOut
                    + ", cardnoOut: " + cardno
                    + ", st: " + st
            );

            CardInfo cardInfo = new CardInfo();
            cardInfo.setRoom(roomOut);
            cardInfo.setGate(gateOut);
            if (stimeOut.length()>0){
                cardInfo.setStarTime(stimeOut.substring(0, 12));
                cardInfo.setEndTime(stimeOut.substring(12, 24));
            }
            cardInfo.setGuestName(guestnameOut);
            cardInfo.setGuestId(guestidOut);
            cardInfo.setCardno(cardno);
            cardInfo.setCardStatus(st);


            respond.setMsg(msg);
            respond.setData(cardInfo);
            return respond;
        } catch (UnsupportedEncodingException e) {
            System.out.println("读卡: byte[] 转 String 异常...");
            e.printStackTrace();
        }
        respond.setStatus(0);
        respond.setMsg("未知异常...");
        return respond;
    }

    @Override
    public Respond destroyCard(CardInfo cardInfo) {
        Respond respond = new Respond();
        respond.setStatus(1);

        // 销卡
        int ret = AidierDLL.INSTANCE.EraseCard(cardInfo.getCardno(), null, null);
        AidierStatus aidierStatus = AidierStatus.fromKey(ret);
        String msg ="卡号: "+cardInfo.getCardno()+ " 状态码: " + aidierStatus.getKey() + ", 说明: " + aidierStatus.getValue();
        log.info("销卡 EraseCard(): " + msg);
        respond.setMsg(msg);
        return respond;
    }

    // beep(蜂鸣器)
    @Override
    public Respond beep() {
        Respond respond = new Respond();
        respond.setStatus(1);

        // 声音和LED状态。11-绿灯1秒，长叫一声；12-红灯1秒，长叫一声；15-红灯1秒，短叫两声；16-短叫一声。
        // 销卡
        int ret = AidierDLL.INSTANCE.Reader_Beep(11);
        AidierStatus aidierStatus = AidierStatus.fromKey(ret);
        String msg =" 状态码: " + aidierStatus.getKey() + ", 说明: " + aidierStatus.getValue();
        log.info("beep(蜂鸣器): " + msg);

        respond.setMsg(msg);
        return respond;
    }


}
